#!/usr/bin/env bash

include "test.sh"

OBJECTV6_ID=1
OBJECTV6_TYPENAME=""

# NewId VAR TYPE
function ObjectV6::NewId()
{
    OBJECTV6__ID=ObjectV6_$((OBJECTV6_ID++))
    eval $1=$OBJECTV6__ID
    eval ${OBJECTV6__ID}TYPE=$2
}

# SetProp VAR NAME VALUE
function ObjectV6::SetProp()
{
    local this="${!1}"; shift
    ObjectV6::SetThisProp "$@"
}

# SetThisProp NAME VALUE
function ObjectV6::SetThisProp()
{
    eval ${this}_$1=$2
}

# GetProp VAR NAME
function ObjectV6::GetProp()
{
    local this="${!1}"; shift
    ObjectV6::GetThisProp "$@"
}

# GetThisProp NAME
function ObjectV6::GetThisProp()
{
    OBJECTV6__NAME=${this}_$1
    eval $1=${!OBJECTV6__NAME}
}

# SetFunc VAR NAME FUNC
function ObjectV6::SetFunc()
{
    local this="${!1}"; shift
    ObjectV6::SetThisFunc "$@"
}

# SetThisFunc NAME FUNC
function ObjectV6::SetThisFunc()
{
    eval ${this}_$1=$2
}

# Call VAR FUNC ARGS...
function ObjectV6::Call()
{
    local this="${!1}"; shift
    ObjectV6::CallThis "$@"
}

# CallThis FUNC ARGS...
function ObjectV6::CallThis()
{
    OBJECTV6__FUNC=${this}_$1; shift
    eval ${!OBJECTV6__FUNC} "$@"
}

# Typeof VAR [TYPENAME]
function ObjectV6::Typeof()
{
    local this="${!1}"; shift
    ObjectV6::TypeofThis "$@"
}

# TypeofThis [TYPENAME]
function ObjectV6::TypeofThis()
{
    if [ "$1" == "" ]; then
        eval "echo \${${this}TYPE}"
    else
        eval "$1=\${${this}TYPE}"
    fi
}

# Instanceof VAR TYPENAME
function ObjectV6::Instanceof()
{
    local this="${!1}"; shift
    ObjectV6::InstanceofThis "$@"
}

# InstanceofThis TYPENAME
function ObjectV6::InstanceofThis()
{
    ObjectV6::TypeofThis OBJECTV6_TYPENAME
    [ "$OBJECTV6_TYPENAME" == "$1" ]
}

function ObjectV6::test1()
{
    function ObjectV6::test1::SetName()
    {
        ObjectV6::SetThisProp name $1
    }

    # NewId Typeof
                              ObjectV6::NewId obj Object
    test::run_cmd             ObjectV6::Typeof obj
    test::should_be           Object

    # SetProp / GetProp
                              ObjectV6::SetProp obj key val
                              ObjectV6::GetProp obj key
    test::var_should_be       key val

    # SetFunc Call
                              ObjectV6::SetFunc obj SetName ObjectV6::test1::SetName
                              ObjectV6::Call obj SetName testname
                              ObjectV6::GetProp obj name
    test::var_should_be       name testname

    # Instanceof
    test::should_return_true  ObjectV6::Instanceof obj Object
    test::should_return_false ObjectV6::Instanceof obj Array
}
test::register_test ObjectV6::test1
